use Term::ANSIColor;

use IPC::Open2;

#print "hello world<br>\n";
sub readCustomizedFiles();
sub analysePatch();
sub getIdentFileVersion($);
sub analyseClasses($);
sub getFileVersion($);
sub matchVersions($$$$$);
sub analyseFiles($);
sub sendMail();
sub printOutput();
sub getPatchDir($);
sub executeCommand($);
#####################################################
##Read the file names/directories etc from the custom 
##file
#####################################################
open(INFILE,"/patches/DBA/customizedfiles.txt");
my %dirFileList=();
my %fileVersions;
my %filePriorities=();
my @errors=();
my @warnings=();
my @notes=();
my $patch=".";
my $patchNum="";
readCustomizedFiles();
close INFILE;


#####################################################
##Start patch analysis
#####################################################
analysePatch();

sub analysePatch()
{
  my @filedirectories=keys(%dirFileList);
  getPatchDir(\@ARGV);
  chdir($patchNum);
  
  #####################################################
  ##Get the list of directories and loop through it.
  ##If class files are involved these need to be handled
  ##slightly differently.We may have to unzip the zip file
  ##that contains the classes before proceeding.
  #####################################################
  foreach $fileDirName (@filedirectories)
  {
    #print $fileDirName,"\n";
    #<STDIN>;
    if($fileDirName =~ /\/oracle\/apps\/([a-zA-Z0-9]{2,3})?\/.*$/)
    {
         analyseClasses($fileDirName);
    }
    else
    {
       analyseFiles($fileDirName);
    }
  }
  printOutput();
  
}
sub getPatchDir($)
{
  my $argsPtr=$_[0];
  my @args=@$argsPtr;
  foreach $arg (@args)
  {
    if($arg =~ /patchtop.*=\s*\/patches\/(.*)$/i)
    {
      $patchNum=$1;
    }
  }
  if(!defined($patchNum) || "" eq $patchNum)
  {
    my $pwd=`pwd`;
    chomp($pwd);
    $pwd =~ /.*\/(.*)$/;
    $patchNum=$1;
  }
  #print $patchNum;
  #<STDIN>;
  if($patchNum =~ /^[0-9]+$/)
  {

     return;
  }
  else
  {
    print color 'red';    
    print "###########################################################################\nPlease run the tool from the patch directory or enter the patchtop option while running the patch \n###########################################################################\n";
    print color 'reset';         
    exit;
  }
}

sub executeCommand($)
{
  my $cmd=$_[0];
  my $pid = open2(*READER, *WRITER, "$cmd" )or die $!;
  my $line="";
  close(WRITER);
  while(<READER>)
  {
    $l_progress="040";
    $line=$_;
    print $line;
    $l_progress="050";
  }
  $l_progress="060";
  close(READER);
  $l_progress="070";
}


sub printOutput()
{
  my $fileChanged=0;  
  my $errorSize=@errors;
  if($errorSize>0)
  {
    $fileChanged=1;
  }

  if(@warnings >0)
  {
    print color 'bold red';  
    @warnings=("=================================================================<br>\n The following files may need to be modified because <br>\n the patch might affect customizations.<br>\n=================================================================<br>\n",@warnings);
    $,="<br>\n";
    print @warnings;
    print color 'reset';    
  }     
  if($fileChanged==0)
  {
    print color 'green';  
    print "Note : There are no changed/superseded files. <br>\n";
    $,="<br>\n";
    print @notes;
    sendMail();    
    print color 'reset';     
    print "Launching adpatch with command : <br>\n adpatch @ARGV";
    #system("adpatch1 @ARGV");
    system("adpatch @ARGV");

  }
  else
  {
    print color 'red';  
    @errors=("################################################################## <br>\n ALERT  CHANGED/SUPERSEDED FILES EXIST THAT HAVE A MAJOR IMPACT . <br>\n Please refer to the output below for details.<br>\n##################################################################<br>\n",@errors);
    $,="<br>\n";
    print @errors;
    print "######################################## <br>\n ADPATCH DID NOT LAUNCH.<br>\n########################################<br>\n<br>\n";    
    print color 'reset';
    #my $warningsExist=@warnings;
    sendMail();    
    exit;
  }  
}
sub analyseClasses($)
{
    my $fileDirName=$_[0];
    my $prod=$1;
    
    my @zipfiles=`ls -1 $patch/*$prod.zip`;
    #print @zipfiles;
    #<STDIN>;
    my $zipFile=$zipfiles[0];
    chomp($zipFile);
    
    #####################################################
    ##If class files are involved these need to be handled
    ##slightly differently.We may have to unzip the zip file
    ##that contains the classes before proceeding.
    #####################################################
    
    if(defined($zipFile))
    {
      $zipFile =~ /(.*)\.zip/;
      my $dir=$1;
      if(-e $dir)
      {
      }
      else
      {
        `unzip $zipFile -d $dir`;
	if(-e $dir)
	{
	}        
	else
	{
          print color 'red';  
	  print "Directory $dir could not be created. Please check permissions and retry\n.";
	  print color 'reset';  
	  exit;
	}
      }
      analyseFiles("$dir/$fileDirName");
    } 
}

sub analyseFiles($)
{
  my $dirName=$_[0];
  if(-e $dirName)
  {
    #####################################################
    ##Get the list of files and their versions in a given directory
    #####################################################
  
    my $fileVerPtr=$dirFileList{$fileDirName};
    %fileVersions=%$fileVerPtr;
    my @custFiles=keys(%fileVersions);
    
    foreach $file (@custFiles)
    {
#      print $file,"\n";
      chomp($file);
      my $fullFileName="$dirName/$file";
      if(-e $fullFileName)
      {
      #print $fullFileName,"\n";
      #<STDIN>;
      
        #####################################################
        ##Get the version of the file by doing an ident first
        ##Then extract the file minor version.
        #####################################################
      
        my $version1 = getIdentFileVersion("$dirName/$file");
        
        chomp($version1);
        my $version=0;
        $version=getFileVersion($version1);
        
        if(exists($fileVersions{$file}))
        {
          #####################################################
          ##Get the version as entered in the custom.txt file
          ##Then extract the file minor version.
          #####################################################        
          my $origVersion=$fileVersions{$file};
          my $originalVersion = getFileVersion($origVersion);
          #####################################################
          ##Compare the original version and the new version to
          ##see if there is a conflict of any sort.
          #####################################################             
          my $errorPtr=matchVersions($originalVersion,$version,$file,$origVersion,$version1)  ;
        }
        
      }
    }
  }
}

sub readCustomizedFiles()
{
  while(<INFILE>)
  {
    #print $_;
    chomp;
    my @list=split(/\s+/);
  #  $,=",";
    #print @list;
    my $prod=$list[0];
    my $dirName= $list[1];
    my $className=$list[2];
    my $classVer=$list[3];
    my $priority=$list[4];
    my %fileVersions=();
    if(exists($dirFileList{$dirName}))
    {
      $fileVerPtr=$dirFileList{$dirName};
      %fileVersions=%$fileVerPtr;
    }  
    $filePriorities{$className}=$priority;
    $fileVersions{$className}=$classVer;
    $dirFileList{$dirName}=\%fileVersions;
  }
}

sub getIdentFileVersion($)
{
  my $file= $_[0];
  $file=~ /(.*)\.*$/;
  my $justFile=$1;  
  my @identOutput=`ident $file`;
  my $version;

  foreach $ident (@identOutput)
  {
    if($fileName =~ /.*\.fmb.*$/)
    {
    if($ident =~ /.*$justFile.*(120.*12010000\.[0-9]+).*$/)
    {
      $version = $1;
      break;
    }
    elsif($ident =~ /.*$justFile.*(120.[0-9]+).*$/)
    {
       $version = $1;
       break;
    }
    }
    else
    {
      if($ident =~ /.*(120.*12010000\.[0-9]+).*$/)
      {
        $version = $1;
        break;
      }
      elsif($ident =~ /.*(120.[0-9]+).*$/)
      {
         $version = $1;
         break;
      }
    }
  }
  return $version;
}

sub getFileVersion($)
{
   my $version;
   my $fileVersion=$_[0];
   if($fileVersion =~ /120.*12010000\.([0-9]+)/)
   {
     $version =$1;      
   }
   elsif($fileVersion =~ /120\.([0-9]+)/)
   {
     $version =$1;      
   } 
   return $version;
}

sub matchVersions($$$$$)
{
   #my @errors=();
  my $originalVersion=$_[0];
  my $version=$_[1];
  my $origVersion=$_[3];
  my $version1=$_[4];
  my $file=$_[2];
  #print  " $originalVersion $version $origVersion $version1  $file\n ";
  if($originalVersion < $version)
  {
     if($filePriorities{$file}==1)
     {
       @errors=(@errors,"Alert:<br>\n========<br>\nFile $file has been superseded by patch $patchNum : <br>\nNew Version : $version1  <br>\nOriginal Version : $origVersion <br>\n<br>\n");
     }
     else
     {
       @warnings=(@warnings,"Warning:<br>\n========<br>\nfile $file has been superseded by patch $patchNum : <br>\nNew Version : $version1  <br>\nOriginal Version : $origVersion <br>\n<br>\n");
     }
  }
  elsif($originalVersion >= $version)
  {
    @notes=(@notes, "Note:<br>\n========<br>\n File $file in patch $patchNum is either lower/same as the deployed file: New Version : $version1 Original Version : $origVersion <br>\n");              
  }
  return \@errors;        
}

sub sendMail()
{
  #print "Starting Send mail 1\n";
  my $sendmail = "/usr/sbin/sendmail -t"; 
  my $reply_to = "Reply-to: arun.sista\@gilead.com\n"; 
  my $subject = ""; 
  if(@errors>1)
  {
   $subject = "Subject: HARD STOP : Patch $patchNum conflicts with customizations\n"; 
  }
  elsif(@warnings>1)
  {
   $subject = "Subject: Patch $patchNum conflicts with customizations\n"; 
  }
  else
  {
    return;
  }
  $,="<br>";
  my $content = "<html><body><p><span style=\"color: red; font-size: 12px;\">
  <strong>  @errors <br><br></span></p> <p ><span style=\"color: orange; font-size: 12px;\">  
  @warnings </p></body></html>"; 
  my $to = "arun.sista\@gilead.com,vineet.patil\@gilead.com,amit.garg\@gilead.com,amit.tagala\@gilead.com,ricky.degun\@gilead.com,nthillaiappan\@gilead.com,tahir.qader\@gilead.com\n"; 
  my $send_to = "To: $to"; 
  open(SENDMAIL, "|$sendmail") or die "Cannot open $sendmail: $!"; 
  print SENDMAIL $reply_to; 
  print SENDMAIL $subject; 
  print SENDMAIL $send_to; 
  print SENDMAIL "Content-type: text/html\n\n"; 
  print SENDMAIL $content; 
  close(SENDMAIL);  
}